package com.aiden.app.common.util

import android.annotation.TargetApi
import android.app.Activity
import android.content.Context
import android.os.Build
import android.view.WindowManager

import java.lang.reflect.InvocationTargetException

/**
 * 获取刘海屏刘海高度工具类
 *
 * @author yanggeng
 * @date 2019/1/7 下午1:34
 */
object NotchUtils {

    private val TAG = NotchUtils::class.java.simpleName

    private val VIVO_NOTCH = 0x00000020 // VIVO是否有刘海
    private val VIVO_NOTCH_HEIGHT_DP = 27 //VIVO刘海高度（dp值）

    private val inXiaomi: Boolean
        get() {
            var defaultVal = 0
            try {
                val cls = Class.forName("android.os.SystemProperties")
                val getMethod = cls.getMethod("getInt", String::class.java, Int::class.javaPrimitiveType)
                defaultVal = getMethod.invoke(cls, "ro.miui.notch", 0) as Int
            } catch (e: Exception) {
                LogUtils.e(TAG, e.message!!)
            }

            return defaultVal == 1
        }

    fun getNotchHeight(activity: Activity, onGetNotchHeightListener: OnGetNotchHeightListener) {
        getInGoogleApi(activity, object : OnGetNotchHeightListener {
            override fun getNotch(notchHeight: Int) {
                if (notchHeight > 0) {
                    val statusBarHeight = getStatusBarHeight(activity)
                    onGetNotchHeightListener.getNotch(if (notchHeight > statusBarHeight) notchHeight else statusBarHeight)
                } else {
                    if (getInHuawei(activity)) {
                        onGetNotchHeightListener.getNotch(getNotchHeightInHuawei(activity))
                    } else if (getInVivo(activity)) {
                        onGetNotchHeightListener.getNotch(getNotchHeightInVivo(activity))
                    } else if (getInOppo(activity)) {
                        onGetNotchHeightListener.getNotch(getNotchHeightInOppo(activity))
                    } else if (inXiaomi) {
                        onGetNotchHeightListener.getNotch(getStatusBarHeight(activity))
                    } else {
                        onGetNotchHeightListener.getNotch(0)
                    }
                }
            }
        })
    }

    fun getStatusBarHeight(context: Context): Int {
        var statusHeight = 0
        val resourceId = context.resources.getIdentifier("status_bar_height", "dimen", "android")
        if (resourceId > 0) {
            statusHeight = context.resources.getDimensionPixelSize(resourceId)
        }
        return statusHeight
    }

    @TargetApi(Build.VERSION_CODES.P)
    private fun getInGoogleApi(activity: Activity, onGetNotchHeightListener: OnGetNotchHeightListener) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
            onGetNotchHeightListener.getNotch(0)
            return
        }
        val decorView = activity.window.decorView
        decorView.post {
            val displayCutout = decorView.rootWindowInsets.displayCutout
            if (displayCutout == null) {
                onGetNotchHeightListener.getNotch(0)
            } else {
                val rects = displayCutout.boundingRects
                if (rects == null || rects.size == 0) {
                    onGetNotchHeightListener.getNotch(0)
                } else {
                    val lp = activity.window.attributes
                    lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
                    activity.window.attributes = lp
                    onGetNotchHeightListener.getNotch(displayCutout.safeInsetTop)
                }
            }
        }
    }

    fun checkNotch(activity: Activity, onGetNotchListener: OnGetNotchListener) {
        getInGoogleApi(activity, object : OnGetNotchHeightListener {
            override fun getNotch(notchHeight: Int) {
                if (notchHeight > 0) {
                    onGetNotchListener.hasNotch(true)
                } else {
                    if (inXiaomi || getInHuawei(activity)
                            || getInVivo(activity) || getInOppo(activity)) {
                        onGetNotchListener.hasNotch(true)
                    } else {
                        onGetNotchListener.hasNotch(false)
                    }
                }
            }
        })
    }

    private fun getInHuawei(activity: Activity): Boolean {
        var hasNotch = false

        try {
            val classLoader = activity.classLoader
            val HwNotchSizeUtil = classLoader.loadClass("com.huawei.android.util.HwNotchSizeUtil")
            val get = HwNotchSizeUtil.getMethod("hasNotchInScreen")
            hasNotch = get.invoke(HwNotchSizeUtil) as Boolean
        } catch (e: ClassNotFoundException) {
            LogUtils.e(TAG, e.message!!)
        } catch (e: NoSuchMethodException) {
            LogUtils.e(TAG, e.message!!)
        } catch (e: IllegalAccessException) {
            LogUtils.e(TAG, e.message!!)
        } catch (e: InvocationTargetException) {
            LogUtils.e(TAG, e.message!!)
        }

        return hasNotch
    }

    private fun getInVivo(activity: Activity): Boolean {
        var hasNotch = false
        try {
            val classLoader = activity.classLoader
            val FtFeature = classLoader.loadClass("android.util.FtFeature")
            val method = FtFeature.getMethod("isFeatureSupport", Int::class.javaPrimitiveType!!)
            hasNotch = method.invoke(FtFeature, VIVO_NOTCH) as Boolean
        } catch (e: ClassNotFoundException) {
            LogUtils.e(TAG, e.message!!)
        } catch (e: IllegalAccessException) {
            LogUtils.e(TAG, e.message!!)
        } catch (e: InvocationTargetException) {
            LogUtils.e(TAG, e.message!!)
        } catch (e: NoSuchMethodException) {
            LogUtils.e(TAG, e.message!!)
        }

        return hasNotch
    }

    private fun getInOppo(activity: Activity): Boolean {
        return activity.packageManager.hasSystemFeature("com.oppo.feature.screen.heteromorphism")
    }

    private fun getNotchHeightInHuawei(activity: Activity): Int {
        var ret = intArrayOf(0, 0)

        try {
            val classLoader = activity.classLoader
            val HwNotchSizeUtil = classLoader.loadClass("com.huawei.android.util.HwNotchSizeUtil")
            val method = HwNotchSizeUtil.getMethod("getNotchSize")
            ret = method.invoke(HwNotchSizeUtil) as IntArray
        } catch (e: ClassNotFoundException) {
            LogUtils.e(TAG, e.message!!)
        } catch (e: IllegalAccessException) {
            LogUtils.e(TAG, e.message!!)
        } catch (e: NoSuchMethodException) {
            LogUtils.e(TAG, e.message!!)
        } catch (e: InvocationTargetException) {
            LogUtils.e(TAG, e.message!!)
        }

        return ret[1]
    }

    private fun getNotchHeightInVivo(activity: Activity): Int {
        return (VIVO_NOTCH_HEIGHT_DP * activity.resources.displayMetrics.density).toInt()
    }

    private fun getNotchHeightInOppo(activity: Activity): Int {
        return 80
    }

    interface OnGetNotchListener {
        fun hasNotch(hasNotch: Boolean)
    }

    interface OnGetNotchHeightListener {
        fun getNotch(notchHeight: Int)
    }
}
